<?php
/**
 * Created by 784855684@qq.com.
 * Link: https://github.com/lichtung/wshore
 * User: linzh
 * Date: 6/25/17
 * Time: 4:48 PM
 */
declare(strict_types=1);


namespace wshore\helper;


use wshore\throws\network\PageNotFountException;
use wshore\throws\NetworkException;

final class Network
{

    const USER_AGENT = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; WOW64; Trident/4.0; SLCC1)';

    public static function touch(string $url)
    {
        $ch = curl_init();
        $curl_opt = [
            CURLOPT_URL, $url,
            CURLOPT_RETURNTRANSFER, 1,
            CURLOPT_TIMEOUT, 1,
        ];
        curl_setopt_array($ch, $curl_opt);
        curl_exec($ch);
        curl_close($ch);
    }


    /**
     * 获取网络url文件内容，加入ua，以解决防采集的站
     * @static
     * @param string $url
     * @return string
     */
    public static function getHtml(string $url): string
    {
        $ch = curl_init();
        $timeout = 4;
        $user_agent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; WOW64; Trident/4.0; SLCC1)";
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        $file_contents = curl_exec($ch);
        curl_close($ch);
        return $file_contents ? $file_contents : '';
    }

    public static function getJson(string $url): array
    {
        $ch = curl_init();
        if (strpos($url, 'https://') === 0) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($ch, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
        }
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_TIMEOUT, 3);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_USERAGENT, self::USER_AGENT);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json; charset=utf-8',
        ]);

        $response = curl_exec($ch);
        if (false === $response) {
            $error = curl_error($ch);
            throw new NetworkException($error);
        } else {
            $resdata = json_decode($response, true);
            if (!$resdata) {
                throw new NetworkException(var_export($response, true));
            } else {
                return $resdata;
            }
        }
    }

    /**
     * @param string $url
     * @param string $cookie
     * @param bool $header
     * @param array $opts
     * @param array $rq_header
     * @return string
     * @throws NetworkException
     * @throws PageNotFountException
     */
    public static function get(string $url, $cookie = '', $header = false, array $opts = [], array $rq_header = [])
    {
        $ch = curl_init($url);
        if (stripos($url, 'https://') !== false) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_SSLVERSION, 1);
        }
        curl_setopt($ch, CURLOPT_HEADER, $header); //将头文件的信息作为数据流输出
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $rq_header and curl_setopt($ch, CURLOPT_HTTPHEADER, $rq_header);
        if ($cookie) {
            if (strpos($cookie, '/') === 0) {
                # linux下绝对路径
                self::touch($cookie);
            }
            curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
            curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
        }
        if ($opts) foreach ($opts as $k => $v) {
            curl_setopt($ch, $k, $v);
        }

        $content = curl_exec($ch);
        $httpCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode === 404) {
            throw new PageNotFountException($url);
        }
        if (false === $content) {
            throw new NetworkException($url);
        }
        return (string)$content;
    }


    /**
     * @param $url
     * @param $fields
     * @param string $cookie
     * @param bool $header
     * @param array $opts
     * @param array $rq_header
     * @return string
     */
    public static function post($url, $fields, $cookie = '', $header = false, array $opts = [], array $rq_header = [])
    {
        $ch = curl_init($url);
        if (stripos($url, 'https://') !== false) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_SSLVERSION, 1);
        }
        curl_setopt($ch, CURLOPT_HEADER, $header); //将头文件的信息作为数据流输出
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
        $rq_header and curl_setopt($ch, CURLOPT_HTTPHEADER, $rq_header);
        if ($cookie) {
            if (strpos($cookie, '/') === 0) {
                self::touch($cookie);
            }
            curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
            curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
        }
        if ($opts) foreach ($opts as $k => $v) {
            curl_setopt($ch, $k, $v);
        }

        $content = curl_exec($ch);
        $httpCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode === 404) {
            throw new PageNotFountException($url);
        }
        if (false === $content) {
            throw new NetworkException($url);
        }
        return (string)$content;
    }

    /**
     * @param string $url
     * @param string|array $data
     * @return array
     * @throws NetworkException
     */
    public static function postJson(string $url, $data): array
    {
        $ch = curl_init();
        if (strpos($url, 'https://') === 0) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($ch, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
        }
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($data) ? json_encode($data) : $data);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_SSLVERSION, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json; charset=utf-8',
        ]);
        $response = curl_exec($ch);
        if ((int)curl_getinfo($ch, CURLINFO_HTTP_CODE) === 404) {
            throw new PageNotFountException($url);
        }
        if (false === $response) {
            throw new NetworkException(curl_error($ch));
        } else {
            $resdata = json_decode($response, true);
            if (!$resdata) {
                throw new NetworkException(var_export($response, true));
            } else {
                return $resdata;
            }
        }
    }


}